package doc2db.fileWorker.xml;

import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * Древовидная обработка <br>
 * Заполняет дерево содержание xml документа
 * @author yura
 */
public class TreeTypeTreatment {
    /**название тегов инфо. части*/
    private String info [];
    /**древовидное содержание xml документа*/
    private TreeTypeNodes tree = null;
    /**заглавный узел - корень дерева*/
    private Node mainNode;

    /**
     *  Конструктор
     * @param info имена тегов для использования
     * @param mainNode корневой узел "info"
     */
    public TreeTypeTreatment(String[] info, Node mainNode) {
        this.info = info;
        this.mainNode = mainNode;
    }

    /**
     *  Проработывает корнивой элемент и строит дерево
     * @return <br>
     * true, если удалось пределить корень <br>
     * false, если нет
     */
    public boolean parseNode(){
        if (mainNode instanceof Element) {} else {
            return false;
        }

        tree = new TreeTypeNodes("null");
        this.initNode(tree, mainNode, tree.getDegreeInward());

        return true;
    }

    /**
     *  Вернуть дерево xml документа
     * @return дерево xml
     */
    public TreeTypeNodes getTreeTypeNodes(){
        return tree;
    }

    /**
     * Распичятывает дерево
     */
    public void print (){
        System.out.println("Tree of info :");
        this.print(tree, "  ");
        System.out.println("Tree ended.");
    }

    /**
     * Рекурсивно распечятывает дерево
     * @param t корневая ветвь дерева
     * @param pref отступ для форматированного вывода
     */
    private void print (TreeTypeNodes t, String pref){
        System.out.print(pref + "\"" + t.getText().replaceAll("\n", "<br>") + "\" [");
        if(t.isFatherElem())
            System.out.print(" mainBranch;");
        else
            System.out.print(" father:\'" + t.getFather().getText()+"\';");
        if(t.isLastElem())
            System.out.print(" lastEleme;");
        else
            System.out.print(" have " + t.getListSize() + " child;");
        System.out.print(" degreeInward=" + t.getDegreeInward());
        System.out.println("]");
        if (! t.isLastElem()) {
            for (int i = 0; i < t.getListSize(); i++) {
                this.print(t.getElemInList(i), pref + "  ");
            }
        }
    }

    /**
     * Инициализировать ветвь дерева
     * @param fatherBranch прорадительская ветвь
     * @param fatherNode прорадительский элемент
     */
    private void initNode(TreeTypeNodes fatherBranch, Node fatherNode, int degree){
        if(! fatherNode.hasChildNodes()){
            fatherBranch.setText("" + this.getDataInNode(fatherNode));
            fatherBranch.setList(null);
            return;
        }

        NodeList list = fatherNode.getChildNodes();

        for (int i = 0; i < list.getLength(); i++) {
            Node child = list.item(i);
            if( (child instanceof Element) || (list.getLength() <= 1) ) {
                if (child.getNodeName().toLowerCase() == "text") {
                    Element e = (Element) child;
                    Text textNode = (Text) e.getFirstChild();
                    String s = textNode.getData().trim();
                    fatherBranch.setText("" + this.getCleanStr(s));
                    fatherBranch.setList(null);
                }else{
                    fatherBranch.addNodeInList("not Entered", fatherBranch, (degree+1));
                    this.initNode(fatherBranch.getElemInList(fatherBranch.getListSize() - 1), child, (degree+1));
                }
            }
        }

    }

    /**
     * информация внутри тега
     * @param node тег
     * @return текст
     */
    private String getDataInNode(Node node){
        /*if (node instanceof Element) {} else {return "ERROR";}
        Element e = (Element) node;
        Text textNode = (Text) e.getFirstChild();
        String s = textNode.getData().trim();*/
        String s = "ERROR";
        try {
            s = node.getNodeValue().trim();
            s = this.getCleanStr(s);
        } catch (DOMException e) {
        }
        return s;
    }

    /**
     * <p>Очищяет строкy, удаляя боковые символы:
     * первый и последний</p>
     * @param str <p>очищяемая строка</p>
     * @return <p>очищенная строка</p>
     */
    private String getCleanStr(String str){
        char data [] = new char[str.length()-2];
        for (int i = 0; i < data.length; i++) {
            data[i] = str.charAt(i + 1);
        }
        return new String (data) ;
    }

}

